package converter;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class JacobDocumentConverter {
	static int WORD_PDF = 17;
	static int WORD_HTML = 8;
	static int WORD_TXT = 7;
	static int EXCEL_PDF = 57;
	static int EXCEL_HTML = 44;
	static int PPT_PDF = 32;
	static Map<String,Integer> docTypeMap = new HashMap<String,Integer>();
    static{
		docTypeMap.put("doc", 1);
		docTypeMap.put("docx", 1);
		docTypeMap.put("ppt", 2);
		docTypeMap.put("pptx", 2);
		docTypeMap.put("pps", 2);
		docTypeMap.put("ppsx", 2);
		docTypeMap.put("xls", 3);
		docTypeMap.put("xlsx", 3);
	}
    private static final Logger logger = Logger.getLogger(JacobDocumentConverter.class);
    private int pageCount;
//    static {
//        if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
//            String dll = "gsdll" + System.getProperty("sun.arch.data.model") + ".dll";
//            URL url = JacobDocumentConverter.class.getResource(dll);
//            String path = url.getPath();
//            System.load(path);
//            logger.info("Load " + dll + " success!");
//            dll = "jacob-1.17-x" + System.getProperty("sun.arch.data.model") + ".dll";
//            url = JacobDocumentConverter.class.getResource(dll);
//            path = url.getPath();
//            System.load(path);
//            logger.info("Load " + dll + " success!");
//        }
//    }
 
    public boolean pdf2png(String source, String pdf, int density) {
        boolean success = true;
//        PDFDocument document = new PDFDocument();
//        try {
//            document.load(new File(source));
//            SimpleRenderer renderer = new SimpleRenderer();
//            pageCount = renderer.getProcessCount();
//            renderer.setResolution(density);
//            List<Image> images = renderer.render(document);
//            for (int i = 0; i < images.size(); i++) {
//                ImageIO.write((RenderedImage) images.get(i), "png", new File((pdf + "/" + i) + ".png"));
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            success = false;
//        }
        return success;
    }
 
    private boolean doc2pdf(String source, String pdf) {
        try {
            ActiveXComponent app = new ActiveXComponent("Word.Application");
            ComThread.InitSTA();
            //设置word不可见
            app.setProperty("Visible", new Variant(false));
            com.jacob.com.Dispatch docs = app.getProperty("Documents").toDispatch();
            /**
             * 第一个true：是否只读
             * 第二个true：是否有标题
             * 第三个false：文件是否可见
             */
            Dispatch doc = Dispatch.call(docs, "Open", source, true, true, false).toDispatch();
            Dispatch.call(doc, "SaveAs", pdf, 17);
            Dispatch.call(doc, "Close", new Variant(false));
            app.invoke("Quit", 0);
            ComThread.Release();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
 
    private boolean ppt2pdf(String source, String pdf) {
        try {
        	ComThread.InitSTA();
            ActiveXComponent app = new ActiveXComponent("PowerPoint.Application");
//            app.setProperty("Visible", new Variant(false));
            Dispatch ppts = app.getProperty("Presentations").toDispatch();
            Dispatch ppt = Dispatch.call(ppts, "Open", source, true, true, false).toDispatch();
            Dispatch.call(ppt, "SaveAs", pdf, 32);
            Dispatch.call(ppt, "Close");
            app.invoke("Quit");
            ComThread.Release();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
 
    private boolean xls2pdf(String source, String pdf) {
        try {
        	ComThread.InitSTA();
            ActiveXComponent app = new ActiveXComponent("Excel.Application");
            app.setProperty("Visible", new Variant(false));
            Dispatch xlses = app.getProperty("Workbooks").toDispatch();
            Dispatch xls = Dispatch.invoke(xlses, "Open", Dispatch.Method, new Object[] { source, true, true }, new int[3]).toDispatch();
            Dispatch.call(xls, "SaveAs", pdf, 57);
            Dispatch.call(xls, "Close",new Variant(false));
            app.invoke("Quit");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }finally{
        	 ComThread.Release();
        }
        return true;
    }
 
    private boolean xls2pdf_V2(String source, String pdf) {
        try {
        	ComThread.InitSTA();
            ActiveXComponent app = new ActiveXComponent("Excel.Application");
            app.setProperty("Visible", new Variant(false));
            Dispatch xlses = app.getProperty("Workbooks").toDispatch();
            Dispatch xls = Dispatch.invoke(xlses, "Open", Dispatch.Method, new Object[] { source, true, true }, new int[3]).toDispatch();
            Dispatch currentSheet = Dispatch.get(xls,"ActiveSheet").toDispatch();
            Dispatch pageSetup = Dispatch.get(currentSheet, "PageSetup").toDispatch();
            Dispatch.put(pageSetup, "Orientation", new Variant(2));
            //如果第一个sheet为空则会抛出异常
            Dispatch.call(currentSheet, "SaveAs", pdf,new Variant(57));
            
//            Dispatch.call(xls, "SaveAs", pdf, 57);
            Dispatch.call(xls, "Close",new Variant(false));
            app.invoke("Quit");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }finally{
        	 ComThread.Release();
        }
        return true;
    }
    
    public boolean saveAsPdf(String source, String pdf) {
        int dotLocation = source.lastIndexOf(".");
        if (dotLocation < 0 || dotLocation + 1 == source.length()) {
            logger.warn("Unknow file type!");
            return false;
        }
        int type = docTypeMap.get(source.substring(dotLocation + 1).toLowerCase());
        boolean result = false;
        switch (type) {
        case 1:
            result = doc2pdf(source, pdf);
            break;
        case 2:
            result = ppt2pdf(source, pdf);
            break;
        case 3:
            result = xls2pdf(source, pdf);
//            result = xls2pdf_V2(source, pdf);
            break;
        default:
            logger.warn("Unknow file type!");
            return false;
        }
        logger.info(String.format("Convert %s to %s %s!", source, pdf, result ? "success" : "fail"));
        return result;
    }
 
    public int getPageCount() {
        return pageCount;
    }
    
    /**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			JacobDocumentConverter convert = new JacobDocumentConverter();
			convert.saveAsPdf(new File("docs/2014.doc").getCanonicalPath(),new File("docs/2014.pdf").getCanonicalPath());
//			convert.saveAsPdf(new File("docs/2015.xlsx").getCanonicalPath(),new File("docs/2015.pdf").getCanonicalPath());
//			convert.saveAsPdf(new File("docs/2016.ppt").getCanonicalPath(),new File("docs/2016.pdf").getCanonicalPath());
//			convert.saveAsPdf(new File("docs/2017.ppt").getCanonicalPath(),new File("docs/2017.pdf").getCanonicalPath());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}